<template>
  <div class>
    <div id="roomcontainer" style="position: relative;" ></div>
    <div id="console">
      <!-- <div id="help">
        帮助：
        <br />快捷键：
        <br />s
        <ul>
          <li>A\&larr;，逆时针转</li>
          <li>D\&rarr;，顺时针转</li>
          <li>W\&uarr;，放大</li>
          <li>S\&darr;，缩小</li>
          <li>Q，左平移</li>
          <li>E，右平移</li>
          <li>R，上旋</li>
          <li>F，下旋</li>
        </ul>
      </div>-->
      <div id="info" style="display: none;">
        log info:
        <br />
      </div>
    </div>
  </div>
</template>
<script>

import {
  pngDevice,
  pngAir,
  pngWall,
  pngDoor,
  pngFire,
  pngServer
} from "./data/pngdata,js";

export default {
  components: {},
  data() {
    return {
      roomid: "",
      roomname: "",
    };
  },
  computed: {},
  watch: {

  },
  mounted() {
    this.roomname = this.$store.state.app.roomname
    this.loaddata();
  },
  methods: {

    loaddata() {

      let _this = this

      // Our Javascript will go here.

      // MAIN

      // standard global variables
      var container = document.getElementById("roomcontainer");
      var scene, camera, renderer, cssrenderer, controls, csscontrols, stats;
      var clock = new THREE.Clock();

      var keyboard = new KeyboardState();

      var SCREEN_WIDTH = window.innerWidth * 0.6,
        SCREEN_HEIGHT = window.innerHeight * 0.6; //

      //var xyz = { x: 0, y: 0, z: 200 };

      // custom global variables
      var targetList = [];
      var projector,
        mouse = {
          x: 0,
          y: 0
        };

      // loginfo
      var info = document.getElementById("info");
      info.style.height = SCREEN_HEIGHT * 0.2 + "px";

      function loginfo(log) {
        info.innerHTML += log;
        info.innerHTML += "<br />";
      }

      // 定义机柜、服务器数据
      var model = [
        {
          cabinet: {
            uuid: "1",
            id: 1,
            name: "1号机柜",
            size: {
              w: 30,
              h: 70,
              d: 30
            }, // 尺寸
            position: {
              x: 0,
              y: 0,
              z: 50
            }, // 位置
            servers: [
              {
                uuid: "11",
                id: 11,
                name: "1号服务器",
                ip: "",
                apps: ""
              }
            ]
          }
        }
      ];

      // 处理服务器打开、关闭时，信息的展示和隐藏
      function openServer(o) {
        loginfo(
          "open:" +
            o.container.info.id +
            "," +
            o.container.info.name +
            "--" +
            o.info.id +
            "," +
            o.info.name
        );
      }

      function closeServer(o) {
        loginfo(
          "close:" +
            o.container.info.id +
            "," +
            o.container.info.name +
            "--" +
            o.info.id +
            "," +
            o.info.name
        );
      }

      // 处理机柜打开、关闭时，信息的展示和隐藏
      function openCabinet(o) {
        loginfo("open:" + o.info.id + "," + o.info.name);
      }

      function closeCabinet(o) {
        loginfo("close:" + o.info.id + "," + o.info.name);
      }

      // 处理鼠标HHover服务器时，服务器信息的内容渲染
      function hoverServer(o) {
        openHover(o.info.uuid, function() {
          // show info
          loginfo(
            "open:" +
              o.container.info.id +
              "," +
              o.container.info.name +
              "--" +
              o.info.id +
              "," +
              o.info.name
          );
        });
      }

      // 处理鼠标HHover机柜时，机柜信息的内容渲染
      function hoverCabinet(o) {
        openHover(o.info.uuid, function() {
          // show info
          loginfo("hover:" + o.info.id + "," + o.info.name);
        });
      }

      // 鼠标Hover时的通用方法
      var curHoverUUID = null;

      function openHover(hoverUUID, callback) {
        if (curHoverUUID == hoverUUID) return;
        curHoverUUID = hoverUUID;

        // 显示Div等操作

        // 回调
        callback();
      }

      function closeHover() {
        curHoverUUID = null;

        // 隐藏Div等操作
      }

      init();
      animate();

      // FUNCTIONS
      function init() {
        // SCENE
        scene = new THREE.Scene();

        // CAMERA
        var VIEW_ANGLE = 50,
          ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT,
          NEAR = 0.1,
          FAR = 2000;

        camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
        // camera = new THREE.OrthographicCamera(-2, 2, 1.5, -1.5, 1, 10);
        scene.add(camera);
        camera.position.set(0, 200, 550);
        camera.lookAt(scene.position);

        // camera.position.z = 5;

        // RENDERER    包括webgl渲染器和css3d渲染器
        //renderer = new THREE.WebGLRenderer();----------------------------
        if (Detector.webgl)
          renderer = new THREE.WebGLRenderer({
            antialias: true
          });
        else renderer = new THREE.CanvasRenderer();

        renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);

        renderer.setClearColor( 0x000000, 0 ); // required
        renderer.setPixelRatio( window.devicePixelRatio );
        // renderer.domElement.style.position = 'absolute'; // required
        renderer.domElement.style.top = 0;
        renderer.domElement.style.zIndex = "1"; // required

        container.appendChild(renderer.domElement);

        //css3d渲染器---------------------------------------------------

        cssrenderer = new THREE.CSS3DRenderer();
        cssrenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
        cssrenderer.domElement.style.position = 'absolute';
        cssrenderer.domElement.style.top = 0;
        container.appendChild( cssrenderer.domElement );



        // CONTROLS
        controls = new THREE.OrbitControls(camera, renderer.domElement);
        csscontrols = new THREE.OrbitControls(camera, cssrenderer.domElement);

        // STATS
        stats = new Stats();
        stats.domElement.style.position = "absolute";
        stats.domElement.style.top = "0px";
        stats.domElement.style.zIndex = 100;
        // container.appendChild(stats.domElement);

        // LIGHT
        var light = new THREE.PointLight(0x00ff00);
        light.position.set(0, 100, 0);
        scene.add(light);

        initModel();

        // initialize object to perform world/screen calculations
        projector = new THREE.Projector();

        // when the mouse moves, call the given function
        document.addEventListener("mousedown", onDocumentMouseDown, false);

        // when the mouse moves, call the given function
        document.addEventListener("mousemove", onDocumentMouseMove, false);
      }

      function initModel() {
        // FLOOR
        createFloor(1024, 800);

        // WALL
        createWall(600, 80, 0, 41, -150, 0, 0, 0);

        createGlassWall(300, 80, 296, 41, 0, 0, Math.PI / 2, 0);
        createGlassWall(300, 80, -296, 41, 0, 0, -Math.PI / 2, 0);

        createGlassWall(100, 80, 296, 41, 210, 0, Math.PI / 2, 0);
        createGlassWall(100, 80, -296, 41, 210, 0, -Math.PI / 2, 0);

        createGlassWall(80, 80, 250, 41, 155, 0, 0, 0);
        createGlassWall(80, 80, -250, 41, 155, 0, 0, 0);

        createGlassWall(300, 80, 0, 41, 155, 0, 0, 0);

        createGlassWall(80, 80, 250, 41, 265, 0, 0, 0);
        createGlassWall(80, 80, -250, 41, 265, 0, 0, 0);

        createGlassWall(300, 80, 0, 41, 265, 0, 0, 0);

        // COLUMN
        createColumn(10, 80, 295, 41, 155);
        createColumn(10, 80, -295, 41, 155);
        createColumn(10, 80, 210, 41, 155);
        createColumn(10, 80, -210, 41, 155);
        createColumn(10, 80, 150, 41, 155);
        createColumn(10, 80, -150, 41, 155);

        createColumn(10, 80, 295, 41, 265);
        createColumn(10, 80, -295, 41, 265);
        createColumn(10, 80, 210, 41, 265);
        createColumn(10, 80, -210, 41, 265);
        createColumn(10, 80, 150, 41, 265);
        createColumn(10, 80, -150, 41, 265);

        createFireExtinguisher(8, 30, 285, 16, 140);
        createFireExtinguisher(8, 30, -285, 16, 140);

        createStandAir(30, 70, 15, 200, 36, -135);
        createStandAir(30, 70, 15, -200, 36, -135);

        var dev1 = createDevice(30, 70, 25, 200, 36, 50, {
          color: 0xffff00,
          uuid: "dev1",
          tooltip: "市电控制柜"
        });
        dev1.hover = function(o) {
          openHover(o.info.uuid, function() {
            loginfo("hover:" + o.info.tooltip);
          });
        };
        var dev2 = createDevice(30, 70, 25, 200, 36, -50, {
          color: 0xff0000,
          uuid: "dev1",
          tooltip: "强电控制柜"
        });
        dev2.hover = function(o) {
          openHover(o.info.uuid, function() {
            loginfo("hover:" + o.info.tooltip);
          });
        };
        var dev3 = createDevice(30, 70, 25, 250, 36, 50, {
          color: 0xff0000,
          uuid: "dev1",
          tooltip: "强电控制柜"
        });
        dev3.hover = function(o) {
          openHover(o.info.uuid, function() {
            loginfo("hover:" + o.info.tooltip);
          });
        };
        var dev4 = createDevice(30, 70, 25, 250, 36, -50, {
          color: 0xcccccc,
          uuid: "dev1",
          tooltip: "空调控制柜"
        });
        dev4.hover = function(o) {
          openHover(o.info.uuid, function() {
            loginfo("hover:" + o.info.tooltip);
          });
        };

        // WINDOW
        
      var windw = createWindow( 245, 50, 0, 41, 156, 0, 0, 0 );
      windw.toggle = function(o) {
        if ( o.rotation.x == 0 ) {
          // o.rotation.x = o.rotation.x + Math.PI / 4;
        } else {
          // o.rotation.x = o.rotation.x - Math.PI / 4;
        }
      }
      

        // DOOR
        var door_right = createDoor(50, 80, 180, 41, 265, 0, 0, 0);
        door_right.toggle = function(o) {
          if (o.rotation.y == 0) {
            o.rotation.y = o.rotation.y + Math.PI / 2;
            o.position.x = o.position.x + 25;
            o.position.z = o.position.z + 25;
          } else {
            o.rotation.y = o.rotation.y - Math.PI / 2;
            o.position.x = o.position.x - 25;
            o.position.z = o.position.z - 25;
          }
        };
        //scene.add(door_right);
        //targetList.push(door_right);

        var door_left = createDoor(50, 80, -180, 41, 265, 0, 0, 0);
        door_left.toggle = function(o) {
          if (o.rotation.y == 0) {
            o.rotation.y = o.rotation.y + Math.PI / 2;
            o.position.x = o.position.x - 25;
            o.position.z = o.position.z + 25;
          } else {
            o.rotation.y = o.rotation.y - Math.PI / 2;
            o.position.x = o.position.x + 25;
            o.position.z = o.position.z - 25;
          }
        };
        //scene.add(door_left);
        //targetList.push(door_left);

        // 创建机柜，

        model = [];

        let row = _.random(0, 5);
        let col = _.random(0, 8);
        // let row = _.random(0, 5)
        // let col = _.random(0, 8)

        for (let serveritemrow = 0; serveritemrow < row; serveritemrow++) {
          for (let serveritemcol = 0; serveritemcol < col; serveritemcol++) {
            model.push({
              cabinet: {
                uuid: "" + serveritemrow + serveritemcol,
                id: "" + serveritemrow + serveritemcol,
                name: "" + serveritemrow + "row" + serveritemcol + "col号机柜",
                size: {
                  w: 30,
                  h: 70,
                  d: 30
                }, // 尺寸 宽、高、深
                position: {
                  x: -300 + 50 * serveritemcol + 50,
                  y: 0,
                  z: -150 + serveritemrow * 50 + 50
                }, // 位置
                servers: [
                  {
                    uuid: "21",
                    id: 21,
                    name: "",
                    ip: "",
                    apps: ""
                  }
                ]
              }
            });
          }
        }

        for (var i = 0; i < model.length; i++) {
          var c = model[i].cabinet;
          createCabinet(
            c.size.w,
            c.size.h,
            c.size.d,
            c.position.x,
            c.position.y,
            c.position.z,
            c
          );
        }

        //添加css3d卡片
        const thing = document.createElement('div');
        thing.style.width = 150+'px';
        thing.style.height = 150+'px';
        thing.style.padding = 10+'px';
        thing.style.backgroundColor = '#555a';

        var child = document.createElement('p');
        child.innerHTML = "名称："+ _this.roomname +"机房<br/>温度： " + _.random(10, 30) + "<br/>湿度：" + _.random(10, 30) + "<br/>CPU平均：" + _.random(10, 90) + "%<br/>内存平均：" + _.random(10, 90) + "%<br/>机柜数量：" + _.random(0, 10) + "个<br/>服务器数量：" + _.random(5, 30) + "台";
        child.style.color = '#fff';
        thing.appendChild(child);

        // thing.style.background = 'url(/home/xuanzhong.png) repeat';
        const objectThing = new THREE.CSS3DObject(thing);
        // objectThing.rotation.x = 1;
        objectThing.position.y = 155;
        objectThing.position.x = 0;
        objectThing.position.z = -150;

        scene.add(objectThing);

        //添加3d文字----------------------------------------------------------------------
        // var loader = new THREE.FontLoader();
        // //导入字体，设定字体，这里的话，你们找对自己的字体路径，可能和我的不一样的！！下载的three.js包里面examples/fonts里面有字体
        // loader.load('/fonts/helvetiker_bold.typeface.json',function(font){
        //   var text = "text3D";
        //   var g = new THREE.TextGeometry(text, {
        //     // 设定文字字体，
        //     font: font,
        //     //尺寸
        //     size: 30,
        //     //厚度
        //     height: 30
        //   });
        //   //计算边界，暂时不用管
        //   g.computeBoundingBox();
        //   //3D文字材质
        //   var m = new THREE.MeshBasicMaterial({ color: 0xff0000 });
        //   var mesh = new THREE.Mesh(g, m);
        //   // 加入到场景中
        //   scene.add(mesh);
            
        // });


        //var cabinet = createCabinet(30, 70, 30, 0, 0, 0 );

        //var cabinet = createCabinet(30, 70, 30, 50, 0, 0 );
        //var cabinet = createCabinet(30, 70, 30, -50, 0, 0 );

        //var cabinet = createCabinet(30, 70, 30, 0, 0, 100 );
        //var cabinet = createCabinet(30, 70, 30, 0, 0, -100 );
      }

      function createCabinet(w, h, d, px, py, pz, c) {
        var cabinet = {};

        // 机柜的后
        var geometry = new THREE.BoxGeometry(w, h, 2);
        var meterial = new THREE.MeshBasicMaterial({
          color: 0x777777,
          opacity: 0.2,
          transparent: true
        });

        var back = new THREE.Mesh(geometry, meterial);

        back.position.x = px;
        back.position.y = py + h / 2 + 1;
        back.position.z = pz - d / 2 + 2;

        back.hover = function(o) {
          hoverCabinet(o.container);
        };
        back.container = cabinet;

        targetList.push(back);
        scene.add(back);
        cabinet.back = back;

        // 机柜的左、右
        var geometry = new THREE.BoxGeometry(w, h, 2);
        var meterial = new THREE.MeshBasicMaterial({
          color: 0x777777,
          opacity: 0.9,
          transparent: true
        });

        var left = new THREE.Mesh(geometry, meterial);
        var right = new THREE.Mesh(geometry, meterial);

        left.position.x = px + w / 2 - 1;
        left.position.y = py + h / 2 + 1;
        left.position.z = pz;
        left.rotation.y = Math.PI / 2;

        right.position.x = px - w / 2 + 1;
        right.position.y = py + h / 2 + 1;
        right.position.z = pz;
        right.rotation.y = -Math.PI / 2;

        left.hover = function(o) {
          hoverCabinet(o.container);
        };
        left.container = cabinet;
        right.hover = function(o) {
          hoverCabinet(o.container);
        };
        right.container = cabinet;

        targetList.push(left);
        targetList.push(right);
        scene.add(left);
        scene.add(right);

        cabinet.left = left;
        cabinet.right = right;

        // 机柜的底部、顶部
        var geometry = new THREE.BoxGeometry(w, 2, d);
        var meterial = new THREE.MeshBasicMaterial({
          color: 0x222222,
          transparent: true
        });

        var top = new THREE.Mesh(geometry, meterial);
        var bottom = new THREE.Mesh(geometry, meterial);

        top.position.x = px;
        top.position.y = py + h + 2;
        top.position.z = pz;

        bottom.position.x = px;
        bottom.position.y = py + 2;
        bottom.position.z = pz;

        top.hover = function(o) {
          hoverCabinet(o.container);
        };
        top.container = cabinet;
        bottom.hover = function(o) {
          hoverCabinet(o.container);
        };
        bottom.container = cabinet;

        targetList.push(top);
        targetList.push(bottom);
        scene.add(top);
        scene.add(bottom);

        cabinet.top = top;
        cabinet.bottom = bottom;

        // 机柜门
        var geometry = new THREE.BoxGeometry(w, h, 2);
        var meterial = new THREE.MeshBasicMaterial({
          color: 0x003333,
          opacity: 0.5,
          transparent: true
        });

        var front = new THREE.Mesh(geometry, meterial);

        front.position.x = px;
        front.position.y = py + h / 2 + 1;
        front.position.z = pz + d / 2;
        front.toggle = function(o) {
          if (o.rotation.y == 0) {
            o.rotation.y = o.rotation.y + (Math.PI * 3) / 5;
            o.position.x = o.position.x + w / 2 + 3;
            o.position.z = o.position.z + d / 2;

            openCabinet(o.container);
          } else {
            o.rotation.y = o.rotation.y - (Math.PI * 3) / 5;
            o.position.x = o.position.x - w / 2 - 3;
            o.position.z = o.position.z - d / 2;

            // 关闭机柜门时，将机柜中的服务器收起
            for (var i = 0; i < o.container.servers.length; i++) {
              o.container.servers[i].toggle(o.container.servers[i], false);
            }

            closeCabinet(o.container);
          }
        };
        front.hover = function(o) {
          hoverCabinet(o.container);
        };
        front.container = cabinet;

        scene.add(front);
        targetList.push(front);

        cabinet.front = front;

        //
        cabinet.servers = [];

        if (c && c.servers) {
          c.servers = [];

          for (let serveritem = 0; serveritem < _.random(0, 10); serveritem++) {
            c.servers.push({
              uuid: "31",
              id: 31,
              name: "",
              ip: "",
              apps: ""
            });
          }

          cabinet.info = c;
          for (var i = 0; i < c.servers.length; i++) {
            var server = createServer(
              w - 4,
              4,
              d - 4,
              px,
              py + 9 * (i + 1),
              pz + 2
            ); // 服务器的厚度默认为 4， 服务器之间的间隔为 5
            server.container = cabinet;
            server.info = c.servers[i];
            cabinet.servers.push(server);
          }
        }

        return cabinet;
      }

      function createServer(w, h, d, px, py, pz) {
        // 服务器
        //var texture = new THREE.ImageUtils.loadTexture( pngServer );
        var texture = new THREE.ImageUtils.loadTexture(
          "/server3d/images/server.png"
        );
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(1, 1);

        var texture_back = new THREE.ImageUtils.loadTexture(
          "/server3d/images/server-back.png"
        );
        texture_back.wrapS = texture_back.wrapT = THREE.RepeatWrapping;
        texture_back.repeat.set(1, 1);

        var geometry = new THREE.BoxGeometry(w, h, d);
        //var material = new THREE.MeshBasicMaterial( { map: texture } );
        // Create an array of materials to be used in a cube, one for each side
        var materialArray = [];
        // order to add materials: x+,x-,y+,y-,z+,z-
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            map: texture
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            map: texture_back
          })
        );
        var material = new THREE.MeshFaceMaterial(materialArray);

        var server = new THREE.Mesh(geometry, material);

        server.position.x = px;
        server.position.y = py;
        server.position.z = pz;

        server.toggle = function(o, openOrClose) {
          // 关闭同一机柜中的其他服务器
          for (var i = 0; i < o.container.servers.length; i++) {
            if (o === o.container.servers[i]) continue;
            if (o.container.servers[i].position.z == pz) {
            } else {
              o.container.servers[i].position.z =
                o.container.servers[i].position.z - d / 2;
              //
              closeServer(o.container.servers[i]);
            }
          }

          if (o.position.z == pz) {
            if (openOrClose == null || openOrClose) {
              o.position.z = o.position.z + d / 2;
              // 打开服务器时，处理其他逻辑
              openServer(o);
            }
          } else {
            if (openOrClose == null || !openOrClose) {
              o.position.z = o.position.z - d / 2;
              // 关上服务器时，处理其他逻辑
              closeServer(o);
            }
          }
        };
        server.hover = function(o) {
          hoverServer(o);
        };

        scene.add(server);
        targetList.push(server);

        return server;
      }

      function createDevice(w, h, d, px, py, pz, info) {
        var texture = new THREE.ImageUtils.loadTexture(pngDevice);
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(1, 1);

        var geometry = new THREE.BoxGeometry(w, h, d);
        //var material = new THREE.MeshBasicMaterial( { map: texture } );
        // Create an array of materials to be used in a cube, one for each side
        var materialArray = [];
        // order to add materials: x+,x-,y+,y-,z+,z-
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            map: texture
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        var material = new THREE.MeshFaceMaterial(materialArray);

        var dev = new THREE.Mesh(geometry, material);

        dev.position.x = px;
        dev.position.y = py;
        dev.position.z = pz;

        scene.add(dev);
        targetList.push(dev);

        dev.info = info;

        //
        var geometry2 = new THREE.BoxGeometry(w + 2, h + 1, d + 2);
        var meterial2 = new THREE.MeshBasicMaterial({
          color: info.color,
          opacity: 0.6,
          transparent: true
        });

        var dev_out = new THREE.Mesh(geometry2, meterial2);
        dev_out.position.x = px;
        dev_out.position.y = py;
        dev_out.position.z = pz;

        scene.add(dev_out);

        return dev;
      }

      function createStandAir(w, h, d, px, py, pz) {
        var texture = new THREE.ImageUtils.loadTexture(pngAir);
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(1, 1);

        var geometry = new THREE.BoxGeometry(w, h, d);
        //var material = new THREE.MeshBasicMaterial( { map: texture } );
        // Create an array of materials to be used in a cube, one for each side
        var materialArray = [];
        // order to add materials: x+,x-,y+,y-,z+,z-
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            map: texture
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        var material = new THREE.MeshFaceMaterial(materialArray);

        var air = new THREE.Mesh(geometry, material);

        air.position.x = px;
        air.position.y = py;
        air.position.z = pz;

        scene.add(air);
        targetList.push(air);

        return air;
      }

      function createFloor(width, height) {
        // FLOOR
        var floorGeometry = new THREE.PlaneGeometry(width, height);
        var floorMaterial = new THREE.MeshBasicMaterial({
          color: 0xcccccc,
          side: THREE.DoubleSide
        });
        var floor = new THREE.Mesh(floorGeometry, floorMaterial);
        //floor.position.x = 0;
        //floor.position.y = 0;
        //floor.position.z = 0;

        floor.rotation.x = Math.PI / 2;

        scene.add(floor);
        targetList.push(floor);

        return floor;
      }

      function createWall(w, h, px, py, pz, rx, ry, rz) {
        var wallTexture = new THREE.ImageUtils.loadTexture(pngWall);
        wallTexture.wrapS = wallTexture.wrapT = THREE.RepeatWrapping;
        wallTexture.repeat.set(w / 20, h / 20);

        var wallGeometry = new THREE.BoxGeometry(w, h, 5);
        var wallMaterial = new THREE.MeshBasicMaterial({
          map: wallTexture,
          side: THREE.DoubleSide
        });
        var wall = new THREE.Mesh(wallGeometry, wallMaterial);
        wall.position.x = px;
        wall.position.y = py;
        wall.position.z = pz;

        wall.rotation.y = ry;

        scene.add(wall);
        targetList.push(wall);

        return wall;
      }

      function createGlassWall(w, h, px, py, pz, rx, ry, rz) {
        var geometry = new THREE.BoxGeometry(w, h, 2);
        var meterial = new THREE.MeshBasicMaterial({
          color: 0x003333,
          opacity: 0.4,
          transparent: true,
          side: THREE.DoubleSide
        });
        var glassW = new THREE.Mesh(geometry, meterial);

        glassW.position.x = px;
        glassW.position.y = py;
        glassW.position.z = pz;

        glassW.rotation.y = ry;

        scene.add(glassW);
        targetList.push(glassW);

        return glassW;
      }

      function createColumn(w, h, px, py, pz) {
        var geometry = new THREE.BoxGeometry(w, h, w);
        var meterial = new THREE.MeshBasicMaterial({
          color: 0xffffff,
          opacity: 1,
          transparent: true,
          side: THREE.DoubleSide
        });
        var column = new THREE.Mesh(geometry, meterial);

        column.position.x = px;
        column.position.y = py;
        column.position.z = pz;

        scene.add(column);
        targetList.push(column);

        return column;
      }

      function createDoor(w, h, px, py, pz, rx, ry, rz) {
        var texture = new THREE.ImageUtils.loadTexture(pngDoor);
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(w / 50, w / 50);

        var geometry = new THREE.BoxGeometry(w, h, 3);
        var material = new THREE.MeshBasicMaterial({
          map: texture,
          side: THREE.DoubleSide
        });
        var door = new THREE.Mesh(geometry, material);
        door.position.x = px;
        door.position.y = py;
        door.position.z = pz;

        scene.add(door);
        targetList.push(door);

        return door;
      }

      function createWindow(w, h, px, py, pz, rx, ry, rz) {
        var geometry = new THREE.PlaneGeometry(w, h);
        var meterial = new THREE.MeshBasicMaterial({
          color: 0x00fff0,
          opacity: 0.5,
          transparent: true,
          side: THREE.DoubleSide
        });
        var windw = new THREE.Mesh(geometry, meterial);

        windw.position.x = px;
        windw.position.y = py;
        windw.position.z = pz;

        scene.add(windw);
        targetList.push(windw);

        return windw;
      }

      function createFireExtinguisher(w, h, px, py, pz) {
        var texture = new THREE.ImageUtils.loadTexture(pngFire);
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set(1, 1);

        //var geometry = new THREE.BoxGeometry(w, h, w);
        var geometry = new THREE.CylinderGeometry(w, w, h, 20, 4);
        //var material = new THREE.MeshBasicMaterial( { map: texture } );

        var materialArray = [];
        materialArray.push(
          new THREE.MeshBasicMaterial({
            map: texture
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        materialArray.push(
          new THREE.MeshBasicMaterial({
            color: 0xbbbbbb
          })
        );
        var material = new THREE.MeshFaceMaterial(materialArray);

        var fe = new THREE.Mesh(geometry, material);
        fe.position.x = px;
        fe.position.y = py;
        fe.position.z = pz;

        scene.add(fe);
        targetList.push(fe);

        //return fe;

        var geometry = new THREE.SphereGeometry(
          w,
          32,
          16,
          0,
          2 * Math.PI,
          0,
          Math.PI / 2
        );
        var material = new THREE.MeshBasicMaterial({
          color: 0xff0000
        });
        var fe = new THREE.Mesh(geometry, material);
        fe.position.x = px;
        fe.position.y = py + h / 2;
        fe.position.z = pz;

        scene.add(fe);
        targetList.push(fe);

        var geometry = new THREE.CylinderGeometry(3, 3, 5, 20, 4);
        var material = new THREE.MeshBasicMaterial({
          color: 0x000000
        });
        var fe = new THREE.Mesh(geometry, material);
        fe.position.x = px;
        fe.position.y = py + h / 2 + w;
        fe.position.z = pz;

        scene.add(fe);
        targetList.push(fe);
      }

      function onDocumentMouseMove(event) {
        // the following line would stop any other event handler from firing
        // (such as the mouse's TrackballControls)
        // event.preventDefault();

        // update the mouse variable
        mouse.x = (event.clientX / SCREEN_WIDTH) * 2 - 1;
        mouse.y = -(event.clientY / SCREEN_HEIGHT) * 2 + 1;

        // find intersections

        // create a Ray with origin at the mouse position
        //   and direction into the scene (camera direction)
        var vector = new THREE.Vector3(mouse.x, mouse.y, 1);
        projector.unprojectVector(vector, camera);
        var ray = new THREE.Raycaster(
          camera.position,
          vector.sub(camera.position).normalize()
        );

        // create an array containing all objects in the scene with which the ray intersects
        var intersects = ray.intersectObjects(targetList);

        // if there is one (or more) intersections
        if (intersects.length > 0) {
          //console.log("Hit @ " + toString( intersects[0].point ) );
          // change the color of the closest face.
          //intersects[ 0 ].face.color.setRGB( 0.8 * Math.random() + 0.2, 0, 0 );
          //intersects[ 0 ].object.geometry.colorsNeedUpdate = true;

          var o = intersects[0].object;
          if (typeof o.hover == "function") {
            o.hover(o);
          } else {
            closeHover();
          }
        }
      }

      function onDocumentMouseDown(event) {
        // the following line would stop any other event handler from firing
        // (such as the mouse's TrackballControls)
        // event.preventDefault();

        //console.log("Click.");

        // update the mouse variable
        mouse.x = (event.clientX / SCREEN_WIDTH) * 2 - 1;
        mouse.y = -(event.clientY / SCREEN_HEIGHT) * 2 + 1;

        // find intersections

        // create a Ray with origin at the mouse position
        //   and direction into the scene (camera direction)
        var vector = new THREE.Vector3(mouse.x, mouse.y, 1);
        projector.unprojectVector(vector, camera);
        var ray = new THREE.Raycaster(
          camera.position,
          vector.sub(camera.position).normalize()
        );

        // create an array containing all objects in the scene with which the ray intersects
        var intersects = ray.intersectObjects(targetList);

        // if there is one (or more) intersections
        if (intersects.length > 0) {
          //console.log("Hit @ " + toString( intersects[0].point ) );
          // change the color of the closest face.
          //intersects[ 0 ].face.color.setRGB( 0.8 * Math.random() + 0.2, 0, 0 );
          //intersects[ 0 ].object.geometry.colorsNeedUpdate = true;

          var o = intersects[0].object;
          if (typeof o.toggle == "function") {
            o.toggle(o);
          }
        }
      }

      function toString(v) {
        return "[ " + v.x + ", " + v.y + ", " + v.z + " ]";
      }

      function animate() {
        requestAnimationFrame(animate);
        render();
        update();
      }

      function update() {
        keyboard.update();

        var moveDistance = 50 * clock.getDelta();

        if (keyboard.pressed("left") || keyboard.pressed("A"))
          camera.translateX(-5);

        if (keyboard.pressed("right") || keyboard.pressed("D"))
          camera.translateX(5);

        if (keyboard.pressed("up") || keyboard.pressed("W"))
          camera.translateZ(-5);

        if (keyboard.pressed("down") || keyboard.pressed("S"))
          camera.translateZ(5);

        if (keyboard.pressed("R")) camera.translateY(-5);

        if (keyboard.pressed("F")) camera.translateY(5);

        if (keyboard.pressed("Q")) controls.pan(new THREE.Vector3(-10, 0, 0));

        if (keyboard.pressed("E")) controls.pan(new THREE.Vector3(10, 0, 0));

        if (keyboard.pressed("Q")) csscontrols.pan(new THREE.Vector3(-10, 0, 0));

        if (keyboard.pressed("E")) csscontrols.pan(new THREE.Vector3(10, 0, 0));

        /*
      if ( keyboard.down("R") )
        mesh.material.color = new THREE.Color(0xff0000);
      if ( keyboard.up("R") )
        mesh.material.color = new THREE.Color(0x0000ff);
      */

        controls.update();
        csscontrols.update();
        stats.update();
      }

      function render() {
        renderer.render(scene, camera);
        cssrenderer.render(scene, camera);
      }
    }
  }
};
</script>
<style lang='scss' scoped>
.aaa {
  backgroundcolor: red;
}
</style>